<?php
/**
 * @depend on: util.php
 */
class Logger
{
    const ERROR = 1;
    const WARN  = 2;
	const INFO  = 3;
    const DEBUG = 4;

    const TYPE_SYSLOG   = "syslog";
    const TYPE_ERRORLOG = "error_log";
    const TYPE_FILE     = "file";
   
	private static $instance;

	private $mLogFilePath        = "/tmp";
	private $mLogFileNamePrefix  = "niced_";
    private $mLogType            = self::TYPE_SYSLOG;//default log type
    private $mLogFileNameFormat  = "Y-m-d-H";
    private $mLogLevel           = self::ERROR;
    //private $mLogType          = "syslog";//file or syslog

    public static $levelmap = array(
        self::ERROR => "ERROR",
        self::WARN  => "WARN",
        self::DEBUG => "DEBUG",
        self::INFO  => "INFO",     
    );

    private static $logTypes = array(
         0 => self::TYPE_SYSLOG,    
         1 => self::TYPE_FILE,
         2 => self::TYPE_ERRORLOG,
    );

    /**
     * @param mixed $level
     *
     */
	public function write($level, $message)
	{
        if (is_numeric($level))
        {
            $level = (int)$level;
            $level = self::$levelmap[$level];
        }

        if (array_search($level, self::$levelmap) > $this->mLogLevel)
        {
            return false;
        }

        if (self::TYPE_SYSLOG == $this->mLogType || self::TYPE_ERRORLOG == $this->mLogType)
        {
            error_log("[".$level."] ".$message);
        }
        else
        {
            $filename = $this->getLogFileName();
            $content = date("[Y-m-d H:i:s]")." [".$level."] ".$message."\n";
            if (!is_writable(dirname($filename)) && !is_writable($filename))
            {
                error_log("log file ".$filename." is not writable");
                error_log("[".$level."] ".$message);
            }
            else
            {
                $bool = Util::writeFile($filename, $content);
            }
        }
	}

	public function getLogFileName()
	{
		return rtrim($this->mLogFilePath, DS).DS.$this->mLogFileNamePrefix."access_log.".date($this->mLogFileNameFormat);
	}

    /**
     * @param string $type file or syslog
     *
     */
    public function setLogType($type)
    {
        if (!in_array($type, self::$logTypes))
        {
            return false;
        }
        else
        {
            $this->mLogType = $type;
            return true;
        }
    }

	public function setLogFilePath($path)
	{
        if (!$path)
        {
            return false;
        }

		$this->mLogFilePath = $path;
        return true;
	}

    public function setLogFileNamePrefix($prefix)
    {
        if (!$prefix)
        {
            return false;
        }

        $this->mLogFileNamePrefix = $prefix;
        return true;
    }

    public function setLogFileNameFormat($format)
    {
        if (!$format)
        {
            return false;
        }

        $this->mLogFileNameFormat = $format;
        return true;
    }

    /**
     * @param int $level
     *
     */
    public function setLogLevel($level)
    {
        if (!$level)
        {
            return false;
        }

        $this->mLogLevel = $level;

        return true;
    }

    public static function formatLogLevel($level)
    {
        return strtoupper($level);
    }

	public static function getInstance($level = NULL, $type = NULL, $filepath = NULL, $filename_prefix = NULL, $filename_format = NULL)
	{
		if (!self::$instance)
		{
			$classname = __CLASS__;
            $logger = new $classname();
            $logger->setLogType($type);
            $logger->setLogLevel($level);
            $logger->setLogFilePath($filepath);
            $logger->setLogFileNamePrefix($filename_prefix);
            $logger->setLogFileNameFormat($filename_format);
			self::$instance = $logger;
		}

		return self::$instance;
	}
} //end class
